package com.googlecode.q2xml.service.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * Example of usage :
 * 
 * <pre>
 * OnlineFromService onfromService = (OnlineFromService) DAOProxy
 * 		.newInstance(new OnlineFormServiceImpl());
 * try {
 * 	Student s = new Student();
 * 	s.setName(&quot;Mohammed&quot;);
 * 	s.setNationalNumber(&quot;123456&quot;);
 * 	onfromService.addStudent(s);
 * } catch (Exception ex) {
 * 	System.out.println(ex.getMessage());
 * }
 * </pre>
 * 
 * @author mohammed hewedy
 * 
 */
public class DAOProxy implements InvocationHandler 
{
	private Object object;
	private Logger logger = Logger.getLogger(this.getClass().getSimpleName());

	private DAOProxy(Object object) {
		this.object = object;
	}

	public static Object newInstance(Object object) {
		return Proxy.newProxyInstance(object.getClass().getClassLoader(),
				object.getClass().getInterfaces(), new DAOProxy(object));
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Class.forName("oracle.jdbc.driver.OracleDriver");
		Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@my_server:1521:xyz", "username", "password");
		Object result = null;
		try 
		{
			Method connectionSetter = object.getClass().getMethod(ProxyConstants.CONNECTION_SETTER_METHOD, Connection.class);
			connectionSetter.invoke(object, conn);
			conn.setAutoCommit(false);
			result = method.invoke(object, args);
			conn.commit();
			return result;
		} catch (Exception ex) 
		{
			ex.printStackTrace();
			conn.rollback();
			Throwable cause = ex.getCause();
			logger.log(Level.SEVERE, cause.getMessage());
			throw new RuntimeException(cause.getMessage(), cause);
		} finally 
		{
			if (conn != null)
				try {conn.close();}catch(Exception ex) {}
		}
	}
}